﻿using System;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using SuperRyoninRPG.Controller;
using SuperRyoninRPG.Main;

namespace SuperRyoninRPG.Characters.Enemys
{

	public enum MoveType
	{
		Stop = 0,
		GoStraight = 1,
		BoundedRandom = 2,
	}

	public enum DieType
	{
		None = 0,
		Jump = 1,
		Vanish = 2,
	}

	public class Enemy : Character
	{
		public bool Crouchable { get; set; }

		private static readonly string imagesFolder = "Images/Enemys";
		private static Random random = new Random();

		public MoveType MoveType { get; set; }

		private float randomWalkTime;
		private int randomWalkMinTime = 5;
		private int randomWalkMaxTime = 15;

		private float randomJumpTime;
		private int randomJumpMinTime = 15;
		private int randomJumpMaxTime = 30;

		private float waitTime;

		public bool Boundable{get;set;}

		protected const float MaxWaitTime = 0.5f;

		public DieType DieType { get; set; }

		private int hitPoint = 1;

		public int HitPoint
		{
			get { return hitPoint; }
			set { hitPoint = value; }
		}

		private struct States
		{
			public const string Normal = "Normal";
		}

		protected override string[] GetStates()
		{
			return new string[0];
		}

		protected override string[] GetActions()
		{
			return new string[0];
		}

		/// <summary>
		///     新しいプレイヤーを構築します。
		/// </summary>
		public Enemy(Stage stage, Vector2 position, MoveType moveType, string name, int frameWidth)
			: base(stage, position, Path.Combine(imagesFolder, name), frameWidth)
		{
			this.Direction = FaceDirection.Left;
			this.MoveType = moveType;
			Initialize();
		}

		public void Initialize()
		{
			//移動の制御
			MaxAcceleration = 5000.0f;
			MaxDushAcceleration = 10000.0f;

			Acceleration = 5000.0f;
			Deceleration = 375f;

			//Jumpの制御
			MaxJumpTime = 1.0f;
			JumpControlPower = 1.0f;
			JumpLaunchVelocity = -300.0f;
			GravityAcceleration = 400.0f;

			this.AllowTurnImage = false;
		}

		/// <summary>
		///     プレイヤーの水平移動とジャンプ コマンドを入力から取得します。
		/// </summary>
		protected override void GetInput(
			GameTime gameTime,
			KeyboardState keyboardState,
			GamePadState gamePadState,
			TouchCollection touchState,
			AccelerometerState accelState,
			DisplayOrientation orientation)
		{
			if (this.MoveType == MoveType.Stop)
			{
				return;
			}
			switch (this.MoveType)
			{
				case MoveType.Stop:
					break;
				case MoveType.GoStraight:
					GetInputStraight(gameTime);
					break;
				case MoveType.BoundedRandom:
					GetInputBoundedRandom(gameTime);
					break;
				default:
					throw new ArgumentOutOfRangeException();
			}
		}

		private void GetInputBoundedRandom(GameTime gameTime)
		{
			if (!this.IsAlive)
			{
				base.Movement = 1.0f;
				return;
			}
			var elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
			this.randomWalkTime -= elapsed;
			this.randomJumpTime -= elapsed;

			if (this.randomWalkTime < 0)
			{
				this.Direction = this.Direction == FaceDirection.Left ? FaceDirection.Right : FaceDirection.Left;
				this.NextRandomWalkTime();
			}

			if (this.randomJumpTime < 0)
			{
				this.IsJumping = true;
				this.NextRandomJumpTime();
			}

			if (this.Direction == FaceDirection.Left)
			{
				this.Movement = -1.0f;
			}
			else
			{
				base.Movement = 1.0f;
			}

		}

		private void GetInputStraight(GameTime gameTime)
		{
			var elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;

			// 歩く方向の側面に基づいてタイルの位置を計算します。
			float posX = this.Position.X + this.LocalBounds.Width / 2 * (int)this.Direction;
			int tileX = (int)Math.Floor(posX / Tile.Width) - (int)this.Direction;
			var tileY = (int)Math.Floor(this.Position.Y / Tile.Height);

			if (this.waitTime > 0)
			{
				// ある程度の時間待機します。
				this.waitTime = Math.Max(0.0f, this.waitTime - (float)gameTime.ElapsedGameTime.TotalSeconds);
				if (this.waitTime <= 0.0f)
				{
					// その後方向転換します。
					this.Direction = (FaceDirection)(-(int)this.Direction);
				}
			}
			else
			{
				// 障壁に衝突しようとした場合、または断崖に落下しようとした場合、
				// 待機を始めます。
				if (this.Stage.GetCollision(tileX + (int)this.Direction, tileY - 1) == TileCollision.Impassable ||
					this.Stage.GetCollision(tileX + (int)this.Direction, tileY) == TileCollision.Passable)
				{
					this.waitTime = MaxWaitTime;
				}
				else
				{
					if (this.Direction == FaceDirection.Right)
					{
						this.Movement = 1;
					}
					else
					{
						this.Movement = -1;
					}
				}
			}
		}

		private void NextRandomWalkTime()
		{
			this.randomWalkTime = GetNextRandomTime(randomWalkMinTime, randomWalkMaxTime);
		}

		private void NextRandomJumpTime()
		{
			this.randomJumpTime = GetNextRandomTime(randomJumpMinTime, this.randomJumpMaxTime);
		}

		private float GetNextRandomTime(int minTime, int maxTime)
		{
			return random.Next(minTime, maxTime) * 0.1f;
		}

		public override void OnDamaged(Character killedBy)
		{
			base.OnDamaged(killedBy);
			this.hitPoint--;
			if (this.hitPoint <= 0)
			{
				this.OnKilled(killedBy);
			}
		}

		public override void OnKilled(Character killedBy)
		{
			base.OnKilled(killedBy);

			switch (this.DieType)
			{
				case DieType.None:
					break;
				case DieType.Jump:
					break;
				case DieType.Vanish:
					break;
				default:
					break;
			}

			
			this.jumpTime = 0;
		}

		private void DieJump()
		{
			this.IsJumping = true;
			this.ForceJump = true;
			DisableCollision = true;
			this.Action = BaseAction.Crouch.ToString(); 
		}


	}
}